package club.zhcs.service.auth;

import static club.zhcs.vo.Application.PAGESIZE;

import java.util.List;

import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.ContinueLoop;
import org.nutz.lang.Each;
import org.nutz.lang.ExitLoop;
import org.nutz.lang.Lang;
import org.nutz.lang.LoopException;

import com.kerbores.utils.collection.Lists;
import com.kerbores.utils.db.SqlActuator;
import com.kerbores.utils.entries.Result;
import com.kerbores.utils.web.pager.Pager;

import club.zhcs.bean.auth.Permission;
import club.zhcs.bean.auth.Role;
import club.zhcs.bean.auth.User.Type;
import club.zhcs.dao.acl.PermissionDao;

/**
 * 
 * @author 王贵源
 *
 * @email kerbores@kerbores.com
 *
 * @description 权限相关业务
 * 
 * @copyright 内部代码,禁止转发
 *
 *
 * @time 2016年1月26日 下午2:37:34
 */
@IocBean
public class PermissionService {
	@Inject
	PermissionDao permissionDao;

	/**
	 * 根据用户查询权限
	 * 
	 * @param id
	 *            用户 id
	 * @param type
	 *            用户类型
	 * @return 权限列表
	 *
	 * @author 王贵源
	 */
	public List<Permission> findByUserId(int id, Type type) {
		final Dao dao = permissionDao.getDao();// 获取数据访问对象

		final List<Permission> permissions = Lists.newArrayList();
		// 获取配置的sql
		Sql sql = dao.sqls().create("select.direct.permission.by.user.id");

		sql.params().set("userId", id);// 注入sql参数
		sql.params().set("type", type);

		List<Record> records = SqlActuator.runReport(sql, dao);// 执行sql
		Lang.each(records, new Each<Record>()// 将记录转换成对象
		{

			@Override
			public void invoke(int index, Record record, int length) throws ExitLoop, ContinueLoop, LoopException {
				permissions.add(record.toEntity(dao.getEntity(Permission.class)));
			}
		});

		return permissions;
	}

	/**
	 * 根据一组角色查询权限
	 * 
	 * @param roles
	 *            角色列表
	 * @return 权限列表
	 *
	 * @author 王贵源
	 */
	public List<Permission> findByRoles(List<Role> roles) {
		if (roles == null || roles.size() == 0) {
			return Lists.newArrayList();
		}
		final int[] temp = new int[roles.size()];
		Lang.each(roles, new Each<Role>() {

			@Override
			public void invoke(int index, Role ele, int length) throws ExitLoop, ContinueLoop, LoopException {
				temp[index] = ele.getId();
			}
		});

		return findByRoles(temp);
	}

	/**
	 * 根据一组角色查询权限
	 * 
	 * @param roles
	 *            角色id 数组
	 * @return 权限列表
	 *
	 * @author 王贵源
	 */
	public List<Permission> findByRoles(int[] roles) {

		if (roles == null || roles.length == 0) {
			return Lists.newArrayList();
		}

		final Dao dao = permissionDao.getDao();// 获取数据访问对象
		final List<Permission> permissions = Lists.newArrayList();
		// 获取配置的sql
		Sql sql = dao.sqls().create("find.permission.by.role");

		sql.setCondition(Cnd.where("r_id", "IN", roles));

		List<Record> records = SqlActuator.runReport(sql, dao);// 执行sql

		Lang.each(records, new Each<Record>()// 将记录转换成对象
		{

			@Override
			public void invoke(int index, Record record, int length) throws ExitLoop, ContinueLoop, LoopException {
				permissions.add(record.toEntity(dao.getEntity(Permission.class)));
			}
		});

		return permissions;
	}

	/**
	 * 根据一组角色查询权限
	 * 
	 * @param roles
	 *            角色 id 列表
	 * @return 权限列表
	 *
	 * @author 王贵源
	 */
	public List<Permission> findByRoleIds(List<Integer> roles) {
		if (roles == null || roles.size() == 0) {
			return Lists.newArrayList();
		}

		final int[] temp = new int[roles.size()];

		Lang.each(roles, new Each<Integer>() {

			@Override
			public void invoke(int index, Integer ele, int length) throws ExitLoop, ContinueLoop, LoopException {
				temp[index] = ele;
			}
		});

		return findByRoles(temp);
	}

	/**
	 * 根据名称查询权限
	 * 
	 * @param name
	 *            权限名称
	 * @return 权限
	 *
	 * @author 王贵源
	 */
	public Permission findByName(String name) {
		return permissionDao.findByCondition(Cnd.where("name", "=", name));
	}

	/**
	 * 添加权限
	 * 
	 * @param permission
	 *            待添加权限
	 * @return 添加之后的权限<将携带数据库 id>
	 *
	 * @author 王贵源
	 */
	public Permission addPermission(Permission permission) {
		return permissionDao.save(permission);
	}

	/**
	 * 查询子权限
	 * 
	 * @param needPermission
	 *            上级权限
	 * @return 子权限列表
	 *
	 * @author 王贵源
	 */
	public List<Permission> findByNeedPermission(int needPermission) {
		return permissionDao.search(Cnd.where("needPermission", "=", needPermission));
	}

	/**
	 * 根据 id 查询
	 * 
	 * @param id
	 *            权限 id
	 * @return 权限
	 *
	 * @author 王贵源
	 */

	public Permission findById(int id) {
		return permissionDao.findById(id);
	}

	/**
	 * 根据权限
	 * 
	 * @param permission
	 *            待更新权限
	 * @param updateField
	 *            待更新字段
	 * @return 更新结果
	 *
	 * @author 王贵源
	 */
	public Result update(Permission permission, String... updateField) {
		return permissionDao.update(permission, updateField) ? Result.success() : Result.fail("更新权限信息失败");
	}

	/**
	 * 根据 url 查询
	 * 
	 * @param url
	 *            参数 url
	 * @return 权限
	 *
	 * @author 王贵源
	 */
	public Permission findByUrl(String url) {
		return permissionDao.findByCondition(Cnd.where("url", "=", url));
	}

	/**
	 * 根据 id 删除
	 * 
	 * @param id
	 *            参数 id
	 * @return 删除结果
	 *
	 * @author 王贵源
	 */
	public Result delete(int id) {
		return permissionDao.delById(id) ? Result.success() : Result.fail("删除权限失败");
	}

	/**
	 * 查询全部
	 * 
	 * @return 全部权限列表
	 *
	 * @author 王贵源
	 */
	public List<Permission> findAll() {
		return permissionDao.findAll();
	}

	/**
	 * 分页查询
	 * 
	 * @param page
	 *            页码
	 * @return 权限分页对象
	 *
	 * @author 王贵源
	 */
	public Pager<Permission> findByPage(int page) {
		Pager<Permission> pager = new Pager<Permission>(PAGESIZE, page);
		pager.setEntities(permissionDao.searchByPage(Cnd.orderBy().asc("id"), page, PAGESIZE));
		pager.setCount(permissionDao.countAll());
		return pager;
	}

	/**
	 * 关键词搜索
	 * 
	 * @param page
	 *            页码
	 * @param key
	 *            关键词
	 * @return 权限分页对象
	 *
	 * @author 王贵源
	 */
	public Pager<Permission> search(int page, String key) {
		Pager<Permission> pager = new Pager<Permission>(PAGESIZE, page);
		key = String.format("%%%s%%", key);
		Cnd cnd = Cnd.where("name", "like", key).or("description", "like", key);
		pager.setEntities(permissionDao.searchByPage(cnd.orderBy("id", "asc"), page, PAGESIZE));
		pager.setCount(permissionDao.countByCnd(cnd));
		return pager;
	}
}
